package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.annotation.PromiseStyleMinVersion
import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.Value2Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.Promise

////////////////////
// Notifications
////////////////////
/**
 * Use the `Browser.notifications` API to create rich notifications using templates and show these notifications to users in the system tray.
 *
 * Permissions: "notifications"
 */
interface Notifications {

    // Clears the specified notification.
    // @return {callback.wasCleared}
    @PromiseStyleMinVersion(116)
     fun clear(
        // The id of the notification to be cleared.
        // This is returned by notifications.create method.
        notificationId: String,
        callback: Value1Function<Boolean>? = null
    ): Promise<Boolean>

    // Creates and displays a notification.
    // @return {callback.notificationId}
    @PromiseStyleMinVersion(116)
     fun create(
        // Identifier of the notification.
        // If not set or empty, an ID will automatically be generated.
        // If it matches an existing notification,
        // this method first clears that notification before proceeding with the create operation.
        // The identifier may not be longer than 500 characters.
        notificationId: String,
        // Contents of the notification.
        options: NotificationOptions,
        callback: Value1Function<String>? = null
    ): Promise<String>

    // Retrieves all the notifications of this app or extension.
    @PromiseStyleMinVersion(116)
     fun getAll(callback: Value1Function<Any>? = null): Promise<Any>

    // Retrieves whether the user has enabled notifications from this app or extension.
    // @return {callback.level}
    @PromiseStyleMinVersion(116)
     fun getPermissionLevel(callback: Value1Function<PermissionLevel>? = null): Promise<PermissionLevel>

    // Updates an existing notification.
    // @return {callback.wasUpdated}
    @PromiseStyleMinVersion(116)
     fun update(
        // The id of the notification to be updated.
        // This is returned by notifications.create method.
        notificationId: String,
        // Contents of the notification to update to.
        options: NotificationOptions,
        callback: Value1Function<Boolean>? = null
    ): Promise<Boolean>

    // The user pressed a button in the notification.
    // @callback {notificationId: string, buttonIndex: number}
     val onButtonClicked: Events.Event<Value2Function<String, Number>>

    // The user clicked in a non-button area of the notification.
    // @callback {notificationId: string}
     val onClicked: Events.Event<Value1Function<String>>

    // The notification closed, either by the system or by user action.
    // @callback {notificationId: string, byUser: boolean}
     val onClosed: Events.Event<Value2Function<String, Boolean>>

    // The user changes the permission level. As of Chrome 47, only ChromeOS has UI that dispatches this event.
     val onPermissionLevelChanged: Events.Event<Value1Function<PermissionLevel>>

    // Custom notification settings button is no longer supported.
    //
    //The user clicked on a link for the app's notification settings.
    // As of Chrome 47, only ChromeOS has UI that dispatches this event.
    // As of Chrome 65, that UI has been removed from ChromeOS, too.
    @Deprecated("Deprecated since Chrome 65")
     val onShowSettings: Events.Event<VoidFunction>

    data class NotificationButton(
        // Button icons not visible for Mac OS X users.
        @Deprecated("Deprecated since Chrome 59")
        var iconUrl: String?,
        var title: String,
    )

    data class NotificationItem(
        // Additional details about this item.
        var message: String,
        // Title of one item of a list notification.
        var title: String,
    )

    data class NotificationOptions(
        // A URL to the app icon mask. URLs have the same restrictions as iconUrl.
        //
        //The app icon mask should be in alpha channel, as only the alpha channel of the image will be considered.
        // The app icon mask is not visible for Mac OS X users.
        @Deprecated("Deprecated since Chrome 59")
        var appIconMaskUrl: String?,
        // Text and icons for up to two notification action buttons.
        var buttons: List<NotificationButton>?,
        // Alternate notification content with a lower-weight font.
        var contextMessage: String?,
        // A timestamp associated with the notification, in milliseconds past the epoch (e.g. Date.now() + n).
        var eventTime: Number?,
        // A URL to the sender's avatar, app icon, or a thumbnail for image notifications.
        //
        //URLs can be a data URL, a blob URL, or a URL relative to a resource within this extension's .crx file
        //
        //**Note:**This value is required for the notifications.create() method.
        var iconUrl: String?,
        // A URL to the image thumbnail for image-type notifications. URLs have the same restrictions as iconUrl.
        // The image is not visible for Mac OS X users.
        @Deprecated("Deprecated since Chrome 59")
        var imageUrl: String?,
        // This UI hint is ignored as of Chrome 67
        @Deprecated("Deprecated since Chrome 67")
        var isClickable: Boolean?,
        // Items for multi-item notifications. Users on Mac OS X only see the first item.
        var items: List<NotificationItem>?,
        // Main notification content.
        //
        //**Note:**This value is required for the notifications.create() method.
        var message: String?,
        // Priority ranges from -2 to 2. -2 is lowest priority. 2 is highest.
        // Zero is default.
        // On platforms that don't support a notification center (Windows, Linux & Mac), -2 and
        // -1 result in an error as notifications with those priorities will not be shown at all.
        var priority: Number?,
        // Current progress ranges from 0 to 100.
        var progress: Number?,
        // Indicates that the notification should remain visible on screen until the user activates or dismisses the notification.
        // This defaults to false.
        @ChromeMinVersion(50)
        var requireInteraction: Boolean?,
        // Indicates that no sounds or vibrations should be made when the notification is being shown.
        // This defaults to false.
        @ChromeMinVersion(70)
        var silent: Boolean?,
        // Title of the notification (e.g. sender name for email).
        //
        //**Note:**This value is required for the notifications.create() method.
        var title: String?,
        // Which type of notification to display. Required for notifications.create method.
        var type: TemplateType?
    )

    enum class PermissionLevel {
        // Specifies that the user has elected to show notifications from the app or extension.
        // This is the default at install time.
        granted,

        // Specifies that the user has elected not to show notifications from the app or extension.
        denied
    }

    enum class TemplateType {
        // Contains an icon, title, message, expandedMessage, and up to two buttons.
        basic,

        // Contains an icon, title, message, expandedMessage, image, and up to two buttons.
        image,

        // Contains an icon, title, message, items, and up to two buttons. Users on Mac OS X only see the first item.
        list,

        // Contains an icon, title, message, progress, and up to two buttons.
        progress,
    }
}